package cc.rengu.redp.bizimpl.upmp.service.impl;

import cc.rengu.redp.bizimpl.constant.UpmpConstant;
import cc.rengu.redp.bizimpl.enums.FeeInputModeEnum;
import cc.rengu.redp.bizimpl.enums.FeeTypeEnum;
import cc.rengu.redp.bizimpl.enums.ProdTypeEnum;
import cc.rengu.redp.bizimpl.upmp.domain.BProdFeeInfo;
import cc.rengu.redp.bizimpl.upmp.dao.BProdFeeInfoMapper;
import cc.rengu.redp.bizimpl.upmp.domain.UpmpSysParam;
import cc.rengu.redp.bizimpl.upmp.service.IBProdFeeInfoService;
import cc.rengu.redp.bizimpl.upmp.service.IUpmpSysParamService;
import cc.rengu.redp.bizimpl.utils.Common;
import cc.rengu.redp.bizimpl.utils.DateUtils;
import cc.rengu.redp.bizimpl.utils.EnumUtils;
import cc.rengu.redp.common.exception.RedpException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author 刘玉亮.LL
 * @since 2021-06-10
 */
@Service
public class BProdFeeInfoServiceImpl extends ServiceImpl<BProdFeeInfoMapper, BProdFeeInfo> implements IBProdFeeInfoService {

    @Autowired
    private IUpmpSysParamService upmpSysParamService;

    /**
     * 查询基础产品费率
     *
     * @param prodType
     * @param baseProdCode
     * @return
     */
    @Override
    public List<BProdFeeInfo> getBaseProdFeeList(String instId, String prodType, String baseProdCode) throws RedpException {
        LambdaQueryWrapper<BProdFeeInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(BProdFeeInfo::getInstId, instId);
        wrapper.eq(BProdFeeInfo::getProdType, prodType);
        wrapper.eq(BProdFeeInfo::getBaseProdCode, baseProdCode);
        wrapper.eq(BProdFeeInfo::getFeeStatus, "01");
        List<BProdFeeInfo> list = this.list(wrapper);
        if (CollectionUtils.isEmpty(list)) {
            wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(BProdFeeInfo::getInstId, upmpSysParamService.getById(UpmpConstant.IGAS_DEFAULT_INST_ID).getPrimaryValue());
            wrapper.eq(BProdFeeInfo::getProdType, prodType);
            wrapper.eq(BProdFeeInfo::getBaseProdCode, baseProdCode);
            wrapper.eq(BProdFeeInfo::getFeeStatus, "01");
            list = this.list(wrapper);
        }
        if (CollectionUtils.isNotEmpty(list)) {
            int now = Integer.valueOf(DateUtils.formatDate(new Date(), DateUtils.FORMAT_YYYYMMDD));
            List<BProdFeeInfo> result = list.stream().filter(item -> (Integer.valueOf(item.getFeeExpiryDate()) > now && Integer.valueOf(item.getFeeEffectiveDate()) <= now)).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(result)) {
                Map<Object, String> map = EnumUtils.EnumToMap(FeeTypeEnum.class);
                for (BProdFeeInfo fee : result) {
                    fee.setRemark1(map.get(fee.getFeeType()));
                }
            }
            return result;
        }
        return list;
    }

    @Override
    public BProdFeeInfo getEffectProdFee(String instId, String prodType, String baseProdCode, String prodCode, String feeType, int date) {
        LambdaQueryWrapper<BProdFeeInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(BProdFeeInfo::getInstId, instId);
        wrapper.eq(BProdFeeInfo::getProdType, prodType);
        if (Common.isNotBlank(prodCode)) {
            wrapper.eq(BProdFeeInfo::getProdCode, prodCode);
        }
        wrapper.eq(BProdFeeInfo::getBaseProdCode, baseProdCode);
        wrapper.eq(BProdFeeInfo::getFeeStatus, "01");
        List<BProdFeeInfo> list = this.list(wrapper);
        List<BProdFeeInfo> result;
        if (CollectionUtils.isNotEmpty(list)) {
            result = list.stream().filter(item -> (Integer.valueOf(item.getFeeExpiryDate()) > date && Integer.valueOf(item.getFeeEffectiveDate()) <= date)).collect(Collectors.toList());
            if (Common.isNotBlank(result) && result.size() > 0) {
                return result.get(0);
            }
        }
        return null;
    }

    /**
     * 界面上 封顶金额/固定金额 都填充在 FeeCappingAmt(封顶金额) 字段 ，需转换
     *
     * @param fee    需要入库的fee
     * @param orgFee 界面传入的fee
     */
    @Override
    public void convertFeeAmt(BProdFeeInfo fee, BProdFeeInfo orgFee) {
        String amt = orgFee.getFeeInputMode();
        if (FeeInputModeEnum.MANUAL_FIX.getType().equals(orgFee.getFeeInputMode())) {
            fee.setFeeRate(null);
            fee.setFeeFixedAmt(orgFee.getFeeCappingAmt());
            fee.setFeeCappingAmt(null);
        } else if (FeeInputModeEnum.MANUAL_RATE_MAX.getType().equals(orgFee.getFeeInputMode())) {
            fee.setFeeRate(orgFee.getFeeRate());
            fee.setFeeFixedAmt(null);
            fee.setFeeCappingAmt(orgFee.getFeeCappingAmt());
        } else if (FeeInputModeEnum.MANUAL_RATE.getType().equals(orgFee.getFeeInputMode())) {
            fee.setFeeRate(orgFee.getFeeRate());
            fee.setFeeFixedAmt(null);
            fee.setFeeCappingAmt(null);
        }
    }


    /**
     * 查询基础产品费率
     *
     * @param instId
     * @param prodType
     * @param baseProdCode
     * @return
     */
    @Override
    public List<BProdFeeInfo> selectBaseProdFeeList(String instId, String prodType, String baseProdCode) throws RedpException {
        LambdaQueryWrapper<BProdFeeInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(BProdFeeInfo::getInstId, instId);
        wrapper.eq(BProdFeeInfo::getProdType, prodType);
        wrapper.eq(BProdFeeInfo::getBaseProdCode, baseProdCode);
        List<BProdFeeInfo> list = this.list(wrapper);
        if (CollectionUtils.isNotEmpty(list)) {
            int now = Integer.valueOf(DateUtils.formatDate(new Date(), DateUtils.FORMAT_YYYYMMDD));
            List<BProdFeeInfo> result = list.stream().filter(item -> (Integer.valueOf(item.getFeeExpiryDate()) > now && Integer.valueOf(item.getFeeEffectiveDate()) <= now)).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(result)) {
                Map<Object, String> map = EnumUtils.EnumToMap(FeeTypeEnum.class);
                for (BProdFeeInfo fee : result) {
                    fee.setRemark1(map.get(fee.getFeeType()));
                }
            }
            return result;
        }
        return list;
    }

    /**
     * 新增时查询查询标准产品费率
     *
     * @param prodType
     * @param baseProdCode
     * @param prodCode
     * @return
     */
    @Override
    public List<BProdFeeInfo> getProdFeeListAdd(String instId, String prodType, String baseProdCode, String prodCode) throws RedpException {
        LambdaQueryWrapper<BProdFeeInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(BProdFeeInfo::getInstId, instId);
        wrapper.eq(BProdFeeInfo::getProdType, prodType);
        wrapper.eq(BProdFeeInfo::getBaseProdCode, baseProdCode);
        wrapper.eq(BProdFeeInfo::getProdCode, prodCode);
        List<BProdFeeInfo> list = this.list(wrapper);
        if (CollectionUtils.isEmpty(list)) {
            list = this.getBaseProdFeeList(instId, ProdTypeEnum.BASE_PROD.getType(), baseProdCode);
        }
        if (CollectionUtils.isNotEmpty(list)) {
            int now = Integer.valueOf(DateUtils.formatDate(new Date(), DateUtils.FORMAT_YYYYMMDD));
            List<BProdFeeInfo> result = list.stream().filter(item -> (Integer.valueOf(item.getFeeExpiryDate()) > now && Integer.valueOf(item.getFeeEffectiveDate()) <= now)).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(result)) {
                Map<Object, String> map = EnumUtils.EnumToMap(FeeTypeEnum.class);
                for (BProdFeeInfo fee : result) {
//                    this.detach(fee);
                    fee.setRemark1(map.get(fee.getFeeType()));
                    fee.setProdCode(prodCode);
                }
            }
            return result;
        }
        return list;
    }

    @Override
    public BProdFeeInfo getEffectProdFeeAdd(String instId, String prodType, String baseProdCode, String prodCode, String feeType, Integer date) {
        LambdaQueryWrapper<BProdFeeInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(BProdFeeInfo::getInstId, instId);
        wrapper.eq(BProdFeeInfo::getProdType, prodType);
        wrapper.eq(BProdFeeInfo::getBaseProdCode, baseProdCode);
        wrapper.eq(BProdFeeInfo::getFeeType, feeType);
        List<BProdFeeInfo> list;
        if (Common.isBlank(prodCode)) {
            list = this.list(wrapper);
        } else {
            wrapper.eq(BProdFeeInfo::getProdCode, prodCode);
            list = this.list(wrapper);
        }
        List<BProdFeeInfo> result;
        if (CollectionUtils.isNotEmpty(list)) {
            result = list.stream().filter(item -> (Integer.valueOf(item.getFeeExpiryDate()) > date && Integer.valueOf(item.getFeeEffectiveDate()) <= date)).collect(Collectors.toList());
            if (Common.isNotBlank(result) && result.size() > 0) {
                return result.get(0);
            }
        }
        return null;
    }

    @Override
    public void delete(List<BProdFeeInfo> listFeeDBDel) {
        for (BProdFeeInfo bProdFeeInfo : listFeeDBDel) {
            this.baseMapper.deleteById(bProdFeeInfo.getId());
        }
    }
}
